1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  package org.apache.tapestry5.internal.services;
16  
17  import java.io.IOException;
18  
19  import org.apache.tapestry5.TrackableComponentEventCallback;
20  import org.apache.tapestry5.internal.InternalConstants;
21  import org.apache.tapestry5.internal.structure.ComponentPageElement;
22  import org.apache.tapestry5.internal.structure.Page;
23  import org.apache.tapestry5.internal.util.Holder;
24  import org.apache.tapestry5.ioc.internal.util.TapestryException;
25  import org.apache.tapestry5.json.JSONObject;
26  import org.apache.tapestry5.services.Ajax;
27  import org.apache.tapestry5.services.ComponentEventRequestHandler;
28  import org.apache.tapestry5.services.ComponentEventRequestParameters;
29  import org.apache.tapestry5.services.ComponentEventResultProcessor;
30  import org.apache.tapestry5.services.Environment;
31  import org.apache.tapestry5.services.Request;
32  
33  
34  
35  
36  
37  @SuppressWarnings({"unchecked", "rawtypes"})
38  public class AjaxComponentEventRequestHandler implements ComponentEventRequestHandler
39  {
40      private final RequestPageCache cache;
41  
42      private final Request request;
43  
44      private final PageRenderQueue queue;
45  
46      private final ComponentEventResultProcessor resultProcessor;
47  
48      private final Environment environment;
49  
50      private final AjaxPartialResponseRenderer partialRenderer;
51  
52      private final PageActivator pageActivator;
53  
54      public AjaxComponentEventRequestHandler(RequestPageCache cache, Request request, PageRenderQueue queue, @Ajax
55      ComponentEventResultProcessor resultProcessor, PageActivator pageActivator,
56                                              Environment environment,
57                                              AjaxPartialResponseRenderer partialRenderer)
58      {
59          this.cache = cache;
60          this.queue = queue;
61          this.resultProcessor = resultProcessor;
62          this.pageActivator = pageActivator;
63          this.request = request;
64          this.environment = environment;
65          this.partialRenderer = partialRenderer;
66      }
67  
68      public void handle(ComponentEventRequestParameters parameters) throws IOException
69      {
70          Page activePage = cache.get(parameters.getActivePageName());
71  
72          final Holder<Boolean> resultProcessorInvoked = Holder.create();
73          resultProcessorInvoked.put(false);
74  
75          ComponentEventResultProcessor interceptor = new ComponentEventResultProcessor()
76          {
77              public void processResultValue(Object value) throws IOException
78              {
79                  resultProcessorInvoked.put(true);
80  
81                  resultProcessor.processResultValue(value);
82              }
83          };
84  
85          
86          
87  
88          queue.setRenderingPage(activePage);
89  
90          request.setAttribute(InternalConstants.PAGE_NAME_ATTRIBUTE_NAME, parameters.getActivePageName());
91  
92          if (pageActivator.activatePage(activePage.getRootElement().getComponentResources(), parameters
93                  .getPageActivationContext(), interceptor))
94              return;
95  
96          Page containerPage = cache.get(parameters.getContainingPageName());
97  
98          ComponentPageElement element = containerPage.getComponentElementByNestedId(parameters.getNestedComponentId());
99  
100         
101         
102         
103 
104         TrackableComponentEventCallback callback = new ComponentResultProcessorWrapper(interceptor);
105 
106         environment.push(ComponentEventResultProcessor.class, interceptor);
107         environment.push(TrackableComponentEventCallback.class, callback);
108 
109         boolean handled = element
110                 .triggerContextEvent(parameters.getEventType(), parameters.getEventContext(), callback);
111 
112         if (!handled)
113             throw new TapestryException(String.format("Request event '%s' (on component %s) was not handled; you must provide a matching event handler method in the component or in one of its containers.", parameters.getEventType(), element.getCompleteId()), element,
114                     null);
115 
116         environment.pop(TrackableComponentEventCallback.class);
117         environment.pop(ComponentEventResultProcessor.class);
118 
119 
120         
121         
122         
123 
124         boolean wasInvoked = resultProcessorInvoked.get();
125 
126         if ((!wasInvoked) && queue.isPartialRenderInitialized())
127         {
128             partialRenderer.renderPartialPageMarkup();
129             return;
130         }
131 
132         
133 
134         if (wasInvoked) { return; }
135 
136         
137         
138         
139 
140         resultProcessor.processResultValue(new JSONObject());
141     }
142 }